#include "windows.h"
#include "VideoOperater.h"

#include "VolumeAdjustment.h"



#define MAX_LOADSTRING 100
#define PLAYER_VOLUME_FULL     0L
#define PLAYER_VOLUME_SILENCE  -10000L
#define IDT_MEDIA_TIMER 100
#define TIMER_PERIOD 500


#define WIDE_VIDEO_WINDOW_WIDTH  640
#define WIDE_VIDEO_WINDOW_HEIGHT 360
#define VIDEO_WINDOW_WIDTH  480
#define VIDEO_WINDOW_HEIGHT 360
#define WIDE_VIDEO_SUBTITLE_WINDOW_WIDTH  640
#define WIDE_VIDEO_SUBTITLE_WINDOW_HEIGHT 100
#define VIDEO_SUBTITLE_WINDOW_WIDTH  480
#define VIDEO_SUBTITLE_WINDOW_HEIGHT 100
#define FULL_VIDEO_SUBTITLE_WINDOW_WIDTH  800
#define FULL_VIDEO_SUBTITLE_WINDOW_HEIGHT 200
#define SECONDARY_VIDEO_WINDOW_WIDTH  720
#define SECONDARY_VIDEO_WINDOW_HEIGHT 576
#define SECONDARY_SCREEN_X_OFFSET     800

//#define SURPPORT_GET_META_DATA

#define msg_dbg  0
#define msg_err  0

typedef enum
{
    ePlayer_init = 0,
    ePlayer_playing,
    ePlayer_paused,
	ePlayer_stopped,
	ePlayer_deinit
} PLAYER_STATE;


PLAYER_STATE  gPlayerState = ePlayer_init;
XAmillisecond gDuration = 0;
XAmillisecond gCurrentMediatime = 0;

//Start of OpenMAX AL Interface
HANDLE  hMutex;
// engine interfaces
static XAObjectItf engineObject = NULL;
static XAEngineItf engineEngine = NULL;

// metadataextraction interfaces
static XAObjectItf metadataObj = NULL;
static XAMetadataExtractionItf metadataExtractionItf = NULL;

// output mix interfaces
static XAObjectItf outputMixObject = NULL;

// media player interfaces
static XAObjectItf playerObj = NULL;
static XAPlayItf   playerPlayItf = NULL;
static XAStreamInformationItf  playerStreamInfoItf = NULL;
static XASeekItf  playerSeekItf = NULL;
static XAVolumeItf             playerVolItf = NULL;
static XAVideoPostProcessingItf    playerVideoPostProcessItf = NULL;
void Player_callback (XAPlayItf caller, void * pContext, XAuint32 event, XAresult result, XAuint32 param, void * pInterface);
XAuint32 scaleOption = XA_VIDEOSCALE_STRETCH;
//End of OpenMAX AL Interface


static BOOL WCharToMByte(LPCWSTR lpcwszStr, LPSTR lpszStr, DWORD dwSize)
{
    DWORD dwMinSize;
    dwMinSize = WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,NULL,0,NULL,FALSE);
    if(dwSize < dwMinSize)
    {
        return FALSE;
    }
    WideCharToMultiByte(CP_OEMCP,NULL,lpcwszStr,-1,lpszStr,dwSize,NULL,FALSE);
    return TRUE;
}

static BOOL MByteToWChar(LPCSTR lpcszStr, LPWSTR lpwszStr, DWORD dwSize,BOOL utf8)
{
    // Get the required size of the buffer that receives the Unicode
    // string.
    DWORD dwMinSize;
    if(utf8 == TRUE)
        dwMinSize = MultiByteToWideChar (CP_UTF8, 0, lpcszStr, -1, NULL, 0);
    else
        dwMinSize = MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, NULL, 0);

    if(dwSize < dwMinSize)
    {
        return FALSE;
    }

    // Convert headers from ASCII to Unicode.
    if(utf8 == TRUE)
        MultiByteToWideChar (CP_UTF8, 0, lpcszStr, -1, lpwszStr, dwMinSize);
    else
        MultiByteToWideChar (CP_ACP, 0, lpcszStr, -1, lpwszStr, dwMinSize);
    return TRUE;
}

void CreateMediaEngine(void)
{
    XAresult res;

    // create engine
    res = xaCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
    ASSERT(XA_RESULT_SUCCESS == res);

    // realize the engine
    res = (*engineObject)->Realize(engineObject, XA_BOOLEAN_FALSE);
    ASSERT(XA_RESULT_SUCCESS == res);

    // get the engine interface, which is needed in order to create other objects
    res = (*engineObject)->GetInterface(engineObject, XA_IID_ENGINE, &engineEngine);
    ASSERT(XA_RESULT_SUCCESS == res);

    // create output mix
    res = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, NULL, NULL);
    ASSERT(XA_RESULT_SUCCESS == res);

    // realize the output mix
    res = (*outputMixObject)->Realize(outputMixObject, XA_BOOLEAN_FALSE);
    ASSERT(XA_RESULT_SUCCESS == res);

}